package impl.gui;

import impl.core.UDecideManager;
import impl.events.UtilityAssertionAddedEvent;
import impl.gui.listeners.UDecideGUIListener;
import impl.gui.util.UDecideGUIElementFactory;
import impl.parser.ExpressionEditorCustom;
import impl.parser.OWLClassExpressionCheckerCustom;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFormattedTextField;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;

import org.protege.editor.core.ui.util.InputVerificationStatusChangedListener;
import org.semanticweb.owlapi.model.OWLClassExpression;

public class UtilityAssertionDialog extends JDialog {

	private JFormattedTextField							uValueField;
	private JButton										addClassExButton;
	private ExpressionEditorCustom<OWLClassExpression>	ClExEditor;

	public UtilityAssertionDialog() {
		super();
		this.setModal(true);
		this.setAlwaysOnTop(true);
		this.setModalityType(ModalityType.APPLICATION_MODAL);
		this.setTitle("Add Utility Assertion to OWLClassExpression");

		// initialise utility value field
		this.uValueField = new JFormattedTextField(NumberFormat.getInstance());
		this.uValueField.setText("0,0");
		this.uValueField.setColumns(20);
		this.uValueField.setHorizontalAlignment(SwingConstants.RIGHT);
		this.uValueField.setBorder(UDecideGUIElementFactory.getBorder("Utility Value (decimal)"));

		// initialise add Button
		this.addClassExButton = new JButton("+ <class expression, utilityValue>");
		this.addClassExButton.setActionCommand("addUtilityAssertion");
		ActionListener addButtonListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String clExString = UtilityAssertionDialog.this.ClExEditor.getText();
				UDecideGUIListener.getInstance().classExpressionAccepted(
						new UtilityAssertionAddedEvent(clExString, UtilityAssertionDialog.this.uValueField.getText()));
			}
		};
		this.addClassExButton.addActionListener(addButtonListener);

		// initialise class expression editor
		this.ClExEditor = new ExpressionEditorCustom<OWLClassExpression>(UDecideManager.getInstance().getOWLEditorKit(), new OWLClassExpressionCheckerCustom(
				UDecideManager.getInstance().getOWLEntityChecker(), UDecideManager.getInstance().getOWLlDataFactory()));
		this.ClExEditor.addStatusChangedListener(new InputVerificationStatusChangedListener() {
			@Override
			public void verifiedStatusChanged(boolean newState) {
				UtilityAssertionDialog.this.addClassExButton.setEnabled(newState);
			}
		});

		// create listener to close dialog with Escape
		ActionListener escListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				setVisible(false);
			}
		};
		// add listener to close dialog with Escape
		this.getRootPane().registerKeyboardAction(escListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);

		// fill side panel
		JPanel sidePanel = new JPanel();
		sidePanel.setLayout(new GridLayout(2, 1));
		sidePanel.add(this.uValueField, BorderLayout.BEFORE_FIRST_LINE);
		sidePanel.add(this.addClassExButton, BorderLayout.AFTER_LAST_LINE);

		// split dialog in half
		JSplitPane dialogSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.ClExEditor, sidePanel);
		dialogSplitter.setResizeWeight(1.0);

		this.add(dialogSplitter);

		this.pack();
		this.setSize(new Dimension(800, 200));
		this.setLocation(((Toolkit.getDefaultToolkit().getScreenSize().width) / 2) - 300,
				((Toolkit.getDefaultToolkit().getScreenSize().height) / 2) - (this.getHeight() / 2));
	}

}